﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using BrightIdeasSoftware;
using LoLHQ.Properties;
using Oyster.Math;

namespace LoLHQ
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            InitAll();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Settings.Default.Save();
        }

        #region Global GUI

        /// <summary>
        /// Set custom behaviour for TAB keys
        /// </summary>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Tab)
            {
                if (champFilter.Focused || champsList.Focused)
                {
                    if (counterUserPicture2.Visible == false)
                    {
                        if (counterUserPicture1.BackColor == Color.LightPink)
                            counterPicture_Click(counterEnemyPicture1, EventArgs.Empty);
                        else
                            counterPicture_Click(counterUserPicture1, EventArgs.Empty);
                    }
                    else
                    {
                        if (counterUserPicture1.BackColor == Color.LightPink)
                            counterPicture_Click(counterUserPicture2, EventArgs.Empty);
                        else if (counterUserPicture2.BackColor == Color.LightPink)
                            counterPicture_Click(counterEnemyPicture1, EventArgs.Empty);
                        else if (counterEnemyPicture1.BackColor == Color.LightPink)
                            counterPicture_Click(counterEnemyPicture2, EventArgs.Empty);
                        else
                            counterPicture_Click(counterUserPicture1, EventArgs.Empty);
                    }
                    return false;
                }
            }
            return base.ProcessDialogKey(keyData);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new OptionsForm(this)).Show();
        }

        private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckForUpdates(true);
        }

        private void summonerSearchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabContainer.SelectedTab = tabSummonerSearch;
        }

        private void teammatesLookupToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabContainer.SelectedTab = tabTeammatesLookup;
        }

        private void counterPicksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabContainer.Contains(tabCounterPicks))
                tabContainer.SelectedTab = tabCounterPicks;
        }

        private void counterPickOverviewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabContainer.Contains(tabCounterPickOverview))
                tabContainer.SelectedTab = tabCounterPickOverview;
        }

        private void championInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabContainer.Contains(tabChampionInformation))
                tabContainer.SelectedTab = tabChampionInformation;
        }

        private void serverChange_Click(object sender, EventArgs e)
        {
            string text = (sender as ToolStripItem).Text;
            if (text.Contains("(NA)"))
                Settings.Default.Server = "na";
            else if (text.Contains("(EUW)"))
                Settings.Default.Server = "euw";
            else if (text.Contains("(EUNE)"))
                Settings.Default.Server = "eune";
            else if (text.Contains("(BR)"))
                Settings.Default.Server = "br";
            else if (text.Contains("(KR)"))
                Settings.Default.Server = "kr";

            CheckServer();
        }

        private void CheckServer()
        {
            northAmericaNAToolStripMenuItem.Checked = europeWestEUWToolStripMenuItem.Checked =
                europeNordicEastEUNEToolStripMenuItem.Checked = brazilBRToolStripMenuItem.Checked =
                koreaKRToolStripMenuItem.Checked = false;

            if (Settings.Default.Server == "na")
                northAmericaNAToolStripMenuItem.Checked = true;
            else if (Settings.Default.Server == "euw")
                europeWestEUWToolStripMenuItem.Checked = true;
            else if (Settings.Default.Server == "eune")
                europeNordicEastEUNEToolStripMenuItem.Checked = true;
            else if (Settings.Default.Server == "br")
                brazilBRToolStripMenuItem.Checked = true;
            else if (Settings.Default.Server == "kr")
                koreaKRToolStripMenuItem.Checked = true;
        }

        private void helpToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Process.Start(Settings.Default.Homepage);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new AboutForm()).Show();
        }

        #endregion

        #region Summoner Search

        private void summonerSearchGo_Click(object sender, EventArgs e)
        {
            // don't do anything if entered search query is too short
            if (summonerName.Text.Length < 2)
                return;

            lolKingLib.GetDataAsync(summonerName.Text);

            lLoadingData.Text = "Loading Data...";
            lLoadingData.Visible = true;
            gRating.Visible = gStatistics.Visible = gMatches.Visible = gChampions.Visible = false;

            summonerName.Text = "";
        }

        void singleSearch_DataReceived(object sender, LOLKingData data)
        {
            // can't find any data
            if (data == null)
            {
                lLoadingData.Text = "Summoner Not Found";
                lLoadingData.Visible = true;
                return;
            }

            // show results
            lName.Text = data.Name;
            lRating.Text = data.Rating.ToString();
            lTopRating.Text = data.TopRating.ToString();
            lWins.Text = data.Wins.ToString();
            lLosses.Text = data.Losses.ToString();
            lChange.Text = data.Change.ToString();

            if (data.Change >= 0)
                lChange.ForeColor = Color.Green;
            else
                lChange.ForeColor = Color.Maroon;

            if (data.Rating >= 850 && data.Rating < 1150)
                lRating.ForeColor = Color.DarkGoldenrod;
            else if (data.Rating >= 1150 && data.Rating < 1500)
                lRating.ForeColor = Color.SteelBlue;
            else if (data.Rating >= 1500 && data.Rating < 1850)
                lRating.ForeColor = Color.Goldenrod;
            else if (data.Rating >= 1850 && data.Rating < 2200)
                lRating.ForeColor = Color.SlateBlue;
            else if (data.Rating >= 2200)
                lRating.ForeColor = Color.RoyalBlue;
            else
                lRating.ForeColor = Color.Black;

            lPentaKills.Text = data.PentaKills.ToString();
            lQuadraKills.Text = data.QuadraKills.ToString();
            lTrippleKills.Text = data.TrippleKills.ToString();
            lDoubleKills.Text = data.DoubleKills.ToString();
            lKills.Text = data.Kills.ToString();
            lMostKills.Text = data.MostKills.ToString();
            lAssists.Text = data.Assists.ToString();
            lLargestKillingSpree.Text = data.LargestKillingSpree.ToString();

            lastMatches.Items.Clear();
            foreach (LastMatchStruct match in data.LastMatches)
            {
                ListViewItem item = new ListViewItem(new string[] { 
                    match.Champion,
                    match.Kind,
                    match.Result,
                    match.When,
                    match.Length,
                    match.KDA,
                    match.Gold,
                    match.CS
                });

                if (match.Result == "Win")
                    item.BackColor = Color.LightGreen;
                else
                    item.BackColor = Color.LightPink;

                lastMatches.Items.Add(item);
            }

            rankedStats.Items.Clear();
            foreach (RankedStatsStruct stats in data.RankedStats)
            {
                int rScore = RScore(stats.Wins + stats.Losses, stats.WinsP, stats.Kills, stats.Deaths, stats.Assists, stats.CS);
                ListViewItem item = new ListViewItem(new string[] { 
                    stats.Champion,
                    stats.Wins.ToString(),
                    stats.Losses.ToString(),
                    stats.WinsP.ToString() + "%",
                    stats.Kills.ToString(),
                    stats.Deaths.ToString(),
                    stats.Assists.ToString(),
                    stats.CS.ToString(),
                    rScore.ToString()
                });

                // calculate color
                item.BackColor = ColorFromHSV(rScore / 100f * 70f + 30f, 0.9, 0.9);
                rankedStats.Items.Add(item);
            }

            // imitate a click on a column - for sorting reasons
            rankedStats_ColumnClick(rankedStats, new ColumnClickEventArgs(8));

            lLoadingData.Visible = false;
            gRating.Visible = gStatistics.Visible = gMatches.Visible = gChampions.Visible = true;
        }

        private void rankedStats_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            Sorter s = (Sorter)rankedStats.ListViewItemSorter;
            s.Column = e.Column;

            if (s.Order == System.Windows.Forms.SortOrder.Ascending)
                s.Order = System.Windows.Forms.SortOrder.Descending;
            else
                s.Order = System.Windows.Forms.SortOrder.Ascending;
            rankedStats.Sort();

        }

        private void summonerName_KeyDown(object sender, KeyEventArgs e)
        {
            // imitate Go click when enter is pressed
            if (e.KeyCode == Keys.Enter)
                summonerSearchGo_Click(this, new EventArgs());
        }

        private void tabPage1_Enter(object sender, EventArgs e)
        {
            // make sure search is focused when entered the tab
            summonerName.Focus();
        }
        #endregion

        #region Lookup
        private void lookupGo_Click(object sender, EventArgs e)
        {
            // clear previous searches
            lookupResults.Items.Clear();
            lookupNames.Clear();

            // add names (only appropriate ones) to lookup array
            foreach (string name in lookUpSearch.Lines)
            {
                string tmp = name.Trim();
                // todo: correct this line
                tmp = tmp.Replace(" joined the room.", "");

                if (tmp.Length < 2)
                    continue;

                lookupNames.Add(tmp);
            }

            // if there any real names in the array, do the search
            if (lookupNames.Count > 0)
            {
                lookupLib.GetDataAsync(lookupNames[0]);

                // indicate the search
                lLookupLoading.Text = "Loading: " + lookupNames[0];
            }

            lLookupLoading.Visible = true;
            gLookupResults.Visible = gLookupStats.Visible = false;
        }

        void lookup_DataReceived(object sender, LOLKingData data)
        {
            lookupNames.RemoveAt(0);

            // if we got any usefull data - show results
            if (data != null)
            {
                string topResult = "";
                List<int> ignore = new List<int>();

                // Display 4 most played champions (or lower amount, if there's not enough data)

                // first
                int t = GetMostPlayedChampionChampion(data, ignore);
                if (t != -1)
                {
                    topResult = data.RankedStats[t].Champion + " [W: " + data.RankedStats[t].WinsP.ToString() + "% of " + (data.RankedStats[t].Wins + data.RankedStats[t].Losses).ToString()
                        + " RS: " + RScore(data.RankedStats[t].Wins + data.RankedStats[t].Losses, data.RankedStats[t].WinsP, data.RankedStats[t].Kills, data.RankedStats[t].Deaths, data.RankedStats[t].Assists, data.RankedStats[t].CS).ToString() + "]";
                    ignore.Add(t);

                    // second
                    t = GetMostPlayedChampionChampion(data, ignore);
                    if (t != -1)
                    {
                        topResult = topResult + ", " + data.RankedStats[t].Champion + " [W: " + data.RankedStats[t].WinsP.ToString() + "% of " + (data.RankedStats[t].Wins + data.RankedStats[t].Losses).ToString()
                            + " RS: " + RScore(data.RankedStats[t].Wins + data.RankedStats[t].Losses, data.RankedStats[t].WinsP, data.RankedStats[t].Kills, data.RankedStats[t].Deaths, data.RankedStats[t].Assists, data.RankedStats[t].CS).ToString() + "]";
                        ignore.Add(t);

                        // third
                        t = GetMostPlayedChampionChampion(data, ignore);
                        if (t != -1)
                        {
                            topResult = topResult + ", " + data.RankedStats[t].Champion + " [W: " + data.RankedStats[t].WinsP.ToString() + "% of " + (data.RankedStats[t].Wins + data.RankedStats[t].Losses).ToString()
                                + " RS: " + RScore(data.RankedStats[t].Wins + data.RankedStats[t].Losses, data.RankedStats[t].WinsP, data.RankedStats[t].Kills, data.RankedStats[t].Deaths, data.RankedStats[t].Assists, data.RankedStats[t].CS).ToString() + "]";
                            ignore.Add(t);

                            // fourth
                            t = GetMostPlayedChampionChampion(data, ignore);
                            if (t != -1)
                            {
                                topResult = topResult + ", " + data.RankedStats[t].Champion + " [W: " + data.RankedStats[t].WinsP.ToString() + "% of " + (data.RankedStats[t].Wins + data.RankedStats[t].Losses).ToString()
                                    + " RS: " + RScore(data.RankedStats[t].Wins + data.RankedStats[t].Losses, data.RankedStats[t].WinsP, data.RankedStats[t].Kills, data.RankedStats[t].Deaths, data.RankedStats[t].Assists, data.RankedStats[t].CS).ToString() + "]";
                                ignore.Add(t);
                            }
                        }
                    }
                }

                ListViewItem item = new ListViewItem(new string[] {
                    data.Name,
                    data.Rating.ToString(),
                    data.TopRating.ToString(),
                    topResult
                });

                lookupResults.Items.Add(item);

                // update stats
                int totalRatings = 0, bestCurrent = 0, worstCurrent = 9999, bestTop = 0, worstTop = 9999;

                foreach (ListViewItem player in lookupResults.Items)
                {
                    totalRatings += Int32.Parse(player.SubItems[1].Text);
                    if (bestCurrent < Int32.Parse(player.SubItems[1].Text))
                        bestCurrent = Int32.Parse(player.SubItems[1].Text);
                    if (worstCurrent > Int32.Parse(player.SubItems[1].Text))
                        worstCurrent = Int32.Parse(player.SubItems[1].Text);
                    if (bestTop < Int32.Parse(player.SubItems[2].Text))
                        bestTop = Int32.Parse(player.SubItems[2].Text);
                    if (worstTop > Int32.Parse(player.SubItems[2].Text))
                        worstTop = Int32.Parse(player.SubItems[2].Text);
                }

                lLookupAverageRating.Text = (totalRatings / lookupResults.Items.Count).ToString();
                lLookupBestCurrentRating.Text = bestCurrent.ToString();
                lLookupWorstCurrentRating.Text = worstCurrent.ToString();
                lLookupBestTopRating.Text = bestTop.ToString();
                lLookupWorstTopRating.Text = worstTop.ToString();
            }

            // regardless if our search was successful or not, check for the next summoner (if any)
            if (lookupNames.Count > 0)
            {
                lLookupLoading.Text = "Loading: " + lookupNames[0];
                lookupLib.GetDataAsync(lookupNames[0]);
            }
            else
            {
                lLookupLoading.Visible = false;
                if (lookupResults.Items.Count > 0)
                    gLookupResults.Visible = gLookupStats.Visible = true;
            }
        }

        private void overviewCreateButton_Click(object sender, EventArgs e)
        {
            if (tOverviewName.Text.Length < 1)
                return;

            File.Create(Application.StartupPath + @"\" + tOverviewName.Text + ".lolhq");

            overviewCreateButton.Enabled = false;
            tOverviewName.Text = "";
            LoadDbList();
        }
        #endregion

        #region Counter Picking

        /// <summary>
        /// Indicates which picturebox is activated
        /// </summary>
        private int activeChamp = 1;

        /// <summary>
        /// Filtering champions list
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void champFilter_TextChanged(object sender, EventArgs e)
        {
            TextMatchFilter filter = TextMatchFilter.Contains(champsList, champFilter.Text);
            champsList.ModelFilter = filter;

            // show filter in the list
            champsList.DefaultRenderer = new HighlightTextRenderer(filter);
        }

        private void champsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            // nothing selected - do nothing
            if (champsList.SelectedItem == null)
                return;

            // get the data structure of currently selected champion
            RiotDataStruct data = riotLib.GetChampionByDisplayName(champsList.SelectedItem.GetSubItem(1).Text);

            PictureBox targetBox = null;
            if (activeChamp == 1)
                targetBox = counterUserPicture1;
            if (activeChamp == 2)
                targetBox = counterUserPicture2;
            if (activeChamp == -1)
                targetBox = counterEnemyPicture1;
            if (activeChamp == -2)
                targetBox = counterEnemyPicture2;

            // show selected champion icon
            targetBox.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + data.IconPath);
            targetBox.Tag = data.Name;

            LoadCountersData(true);
        }


        private void counterPicture_Click(object sender, EventArgs e)
        {
            if ((sender as PictureBox).Name == "counterUserPicture1")
                activeChamp = 1;
            if ((sender as PictureBox).Name == "counterUserPicture2")
                activeChamp = 2;
            if ((sender as PictureBox).Name == "counterEnemyPicture1")
                activeChamp = -1;
            if ((sender as PictureBox).Name == "counterEnemyPicture2")
                activeChamp = -2;

            counterUserPicture1.BackColor = counterUserPicture2.BackColor = counterEnemyPicture1.BackColor = counterEnemyPicture2.BackColor = Color.White;
            (sender as PictureBox).BackColor = Color.LightPink;
        }

        private void rKind_Click(object sender, EventArgs e)
        {
            if (rSolo.Checked || rJungling.Checked)
            {
                counterPicture_Click(counterUserPicture1, new EventArgs());
                counterUserPicture2.Visible = counterEnemyPicture2.Visible = false;
            }
            else
            {
                counterUserPicture2.Visible = counterEnemyPicture2.Visible = true;
            }

            LoadCountersData(true);
        }

        private void champFilter_KeyDown(object sender, KeyEventArgs e)
        {
            // immitate selection change on ENTER key
            if (e.KeyCode == Keys.Enter)
                if (champsList.Items.Count > 0)
                    champsList.SelectedIndex = 0;

            if (e.KeyCode == Keys.Escape)
                champFilter.Text = "";

            if (e.KeyCode == Keys.Tab)
            {
                e.Handled = true;
                e.SuppressKeyPress = true;
                
            }
        }

        private string GetKey()
        {
            // generate key
            if (rDuo.Checked)
                return "d";
            else if (rJungling.Checked)
                return "j";

            return "s";
        }

        private void saveNotes_Click(object sender, EventArgs e)
        {
            string topic = "";
            string key = GetKey();
            string value = "";
            bool reversed = false;

            if (key != "d")
                reversed = GetRecordId(key, counterUserPicture1.Tag.ToString(), null, counterEnemyPicture1.Tag.ToString(), null, out topic);
            else
                reversed = GetRecordId(key, counterUserPicture1.Tag.ToString(), counterUserPicture2.Tag.ToString(), counterEnemyPicture1.Tag.ToString(), counterEnemyPicture2.Tag.ToString(), out topic);

            // generate value
            if (!reversed)
                value = sOverall.Value.ToString() + "|" + sOne.Value.ToString() + "|" + sFarming.Value.ToString() + "|" + sTeamFighting.Value.ToString() + "|" + tNotes.Text;
            else
                value = (-sOverall.Value).ToString() + "|" + (-sOne.Value).ToString() + "|" + (-sFarming.Value).ToString() + "|" + (-sTeamFighting.Value).ToString() + "|" + tNotes.Text;

            lolDb.WriteEntry(topic, key, value);

            LoadCountersData(true);
            saveNotes.Enabled = false;
            champFilter.Focus();
        }


        private void LoadCountersData(bool updateList)
        {
            saveNotes.Enabled = false;
            counterStatsGrid.Visible = false;

            if (counterUserPicture1.Tag == null)
                return;

            if (updateList)
                UpdateCountersList();

            if (counterEnemyPicture1.Tag == null)
                return;

            if (rDuo.Checked)
                if (counterUserPicture2.Tag == null || counterEnemyPicture2.Tag == null)
                    return;

            string topic = "";
            string key = GetKey();
            string value = "";
            bool reversed = false;

            if (key != "d")
                reversed = GetRecordId(key, counterUserPicture1.Tag.ToString(), null, counterEnemyPicture1.Tag.ToString(), null, out topic);
            else
                reversed = GetRecordId(key, counterUserPicture1.Tag.ToString(), counterUserPicture2.Tag.ToString(), counterEnemyPicture1.Tag.ToString(), counterEnemyPicture2.Tag.ToString(), out topic);


            value = lolDb.ReadEntry(topic, key);
            if (value != null) // info found
            {
                deleteNotes.Visible = true;

                string[] tmp = value.Split('|');

                sOverall.Value = reversed ? -Int32.Parse(tmp[0]) : Int32.Parse(tmp[0]);
                sOne.Value = reversed ? -Int32.Parse(tmp[1]) : Int32.Parse(tmp[1]);
                sFarming.Value = reversed ? -Int32.Parse(tmp[2]) : Int32.Parse(tmp[2]);
                sTeamFighting.Value = reversed ? -Int32.Parse(tmp[3]) : Int32.Parse(tmp[3]);
                tNotes.Text = tmp[4];

                counterStatsGrid.Visible = true;
                UpdateCounterStats();
            }
            else // no data - reset
            {
                deleteNotes.Visible = false;

                sOverall.Value = 0;
                sOne.Value = 0;
                sFarming.Value = 0;
                sTeamFighting.Value = 0;
                tNotes.Text = "";

                counterStatsGrid.Visible = true;
                UpdateCounterStats();
            }
        }

        public void UpdateCounterStats()
        {
            RiotDataStruct champ1 = riotLib.GetChampionByName(counterUserPicture1.Tag.ToString());
            RiotDataStruct champ2 = riotLib.GetChampionByName(counterEnemyPicture1.Tag.ToString());

            counterStatsGrid.AutoGenerateColumns = false;

            // populate stats table
            List<CompareStatsStruct> list = new List<CompareStatsStruct>();
            list.Add(new CompareStatsStruct()
            {
                Name = "Range",
                Base1 = champ1.Range.ToString("F1"),
                Level1 = "",
                Diff = (champ1.Range - champ2.Range).ToString("F"),
                Base2 = champ2.Range.ToString("F1"),
                Level2 = ""
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Move Speed",
                Base1 = champ1.MoveSpeed.ToString("F1"),
                Level1 = "",
                Diff = (champ1.MoveSpeed - champ2.MoveSpeed).ToString("F"),
                Base2 = champ2.MoveSpeed.ToString("F1"),
                Level2 = ""
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Attack",
                Base1 = champ1.AttackBase.ToString("F1"),
                Level1 = champ1.AttackLevel.ToString("F1"),
                Diff = ((champ1.AttackBase + (champ1.AttackLevel * 18)) - (champ2.AttackBase + (champ2.AttackLevel * 18))).ToString("F"),
                Base2 = champ2.AttackBase.ToString("F1"),
                Level2 = champ2.AttackLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Armor",
                Base1 = champ1.ArmorBase.ToString("F1"),
                Level1 = champ1.ArmorLevel.ToString("F1"),
                Diff = ((champ1.ArmorBase + (champ1.ArmorLevel * 18)) - (champ2.ArmorBase + (champ2.ArmorLevel * 18))).ToString("F"),
                Base2 = champ2.ArmorBase.ToString("F1"),
                Level2 = champ2.ArmorLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Magic Resist",
                Base1 = champ1.MagicResistBase.ToString("F1"),
                Level1 = champ1.MagicResistLevel.ToString("F1"),
                Diff = ((champ1.MagicResistBase + (champ1.MagicResistLevel * 18)) - (champ2.MagicResistBase + (champ2.MagicResistLevel * 18))).ToString("F"),
                Base2 = champ2.MagicResistBase.ToString("F1"),
                Level2 = champ2.MagicResistLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Health",
                Base1 = champ1.HealthBase.ToString("F1"),
                Level1 = champ1.HealthLevel.ToString("F1"),
                Diff = ((champ1.HealthBase + (champ1.HealthLevel * 18)) - (champ2.HealthBase + (champ2.HealthLevel * 18))).ToString("F"),
                Base2 = champ2.HealthBase.ToString("F1"),
                Level2 = champ2.HealthLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Health Regen",
                Base1 = champ1.HealthRegenBase.ToString("F1"),
                Level1 = champ1.HealthRegenLevel.ToString("F1"),
                Diff = ((champ1.HealthRegenBase + (champ1.HealthRegenLevel * 18)) - (champ2.HealthRegenBase + (champ2.HealthRegenLevel * 18))).ToString("F"),
                Base2 = champ2.HealthRegenBase.ToString("F1"),
                Level2 = champ2.HealthRegenLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Mana",
                Base1 = champ1.ManaBase.ToString("F1"),
                Level1 = champ1.ManaLevel.ToString("F1"),
                Diff = ((champ1.ManaBase + (champ1.ManaLevel * 18)) - (champ2.ManaBase + (champ2.ManaLevel * 18))).ToString("F"),
                Base2 = champ2.ManaBase.ToString("F1"),
                Level2 = champ2.ManaLevel.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Mana Regen",
                Base1 = champ1.ManaRegenBase.ToString("F1"),
                Level1 = champ1.ManaRegenLevel.ToString("F1"),
                Diff = ((champ1.ManaRegenBase + (champ1.ManaRegenLevel * 18)) - (champ2.ManaRegenBase + (champ2.ManaRegenLevel * 18))).ToString("F"),
                Base2 = champ2.ManaRegenBase.ToString("F1"),
                Level2 = champ2.ManaRegenLevel.ToString("F1")
            });

            counterStatsGrid.DataSource = list;

            // colorize results
            for (int row = 0; row < counterStatsGrid.Rows.Count; row++)
            {
                // base column
                if (Double.Parse(counterStatsGrid.Rows[row].Cells[1].Value.ToString()) > Double.Parse(counterStatsGrid.Rows[row].Cells[4].Value.ToString()))
                {
                    counterStatsGrid.Rows[row].Cells[1].Style.ForeColor = Color.DarkGreen;
                    counterStatsGrid.Rows[row].Cells[4].Style.ForeColor = Color.Maroon;
                }
                else if (Double.Parse(counterStatsGrid.Rows[row].Cells[1].Value.ToString()) < Double.Parse(counterStatsGrid.Rows[row].Cells[4].Value.ToString()))
                {
                    counterStatsGrid.Rows[row].Cells[1].Style.ForeColor = Color.Maroon;
                    counterStatsGrid.Rows[row].Cells[4].Style.ForeColor = Color.DarkGreen;
                }
                else
                {
                    counterStatsGrid.Rows[row].Cells[1].Style.ForeColor = Color.DarkBlue;
                    counterStatsGrid.Rows[row].Cells[4].Style.ForeColor = Color.DarkBlue;
                }

                // level column
                if (counterStatsGrid.Rows[row].Cells[2].Value.ToString().Length > 0 && counterStatsGrid.Rows[row].Cells[5].Value.ToString().Length > 0)
                {
                    if (Double.Parse(counterStatsGrid.Rows[row].Cells[2].Value.ToString()) > Double.Parse(counterStatsGrid.Rows[row].Cells[5].Value.ToString()))
                    {
                        counterStatsGrid.Rows[row].Cells[2].Style.ForeColor = Color.DarkGreen;
                        counterStatsGrid.Rows[row].Cells[5].Style.ForeColor = Color.Maroon;
                    }
                    else if (Double.Parse(counterStatsGrid.Rows[row].Cells[2].Value.ToString()) < Double.Parse(counterStatsGrid.Rows[row].Cells[5].Value.ToString()))
                    {
                        counterStatsGrid.Rows[row].Cells[2].Style.ForeColor = Color.Maroon;
                        counterStatsGrid.Rows[row].Cells[5].Style.ForeColor = Color.DarkGreen;
                    }
                    else
                    {
                        counterStatsGrid.Rows[row].Cells[2].Style.ForeColor = Color.DarkBlue;
                        counterStatsGrid.Rows[row].Cells[5].Style.ForeColor = Color.DarkBlue;
                    }
                }

                // diff column
                if (Double.Parse(counterStatsGrid.Rows[row].Cells[3].Value.ToString()) > 0.01f)
                    counterStatsGrid.Rows[row].Cells[3].Style.BackColor = Color.LightGreen;
                else if (Double.Parse(counterStatsGrid.Rows[row].Cells[3].Value.ToString()) < -0.01f)
                    counterStatsGrid.Rows[row].Cells[3].Style.BackColor = Color.LightPink;
                else
                    counterStatsGrid.Rows[row].Cells[3].Style.BackColor = Color.LightBlue;
            }
        }

        public void UpdateCountersList()
        {
            string key = GetKey();

            // build counters list
            List<ChampCountersListStruct> counters = lolDb.GetCounters(key, (string)(counterUserPicture1.Tag), counterUserPicture2.Tag == null ? "" : (string)(counterUserPicture2.Tag));
            countersList.Items.Clear();
            countersList.SetObjects(counters);
            countersList.Sort(countersScoreColumn, SortOrder.Descending);
        }

        private void countersList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (countersList.SelectedItem == null)
                return;


            string selected = countersList.SelectedItem.GetSubItem(2).Text;

            if (selected.Contains("/"))
            {
                string[] tmp = selected.Split('/');
                RiotDataStruct data1 = riotLib.GetChampionByName(tmp[0]);

                counterEnemyPicture1.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + data1.IconPath);
                counterEnemyPicture1.Tag = data1.Name;

                RiotDataStruct data2 = riotLib.GetChampionByName(tmp[1]);

                counterEnemyPicture2.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + data2.IconPath);
                counterEnemyPicture2.Tag = data2.Name;

            }
            else
            {
                RiotDataStruct data = riotLib.GetChampionByName(selected);

                counterEnemyPicture1.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + data.IconPath);
                counterEnemyPicture1.Tag = data.Name;

            }

            LoadCountersData(false);
        }

        private void sSlider_ValueChanged(object sender, EventArgs e)
        {
            saveNotes.Enabled = true;
        }

        private void tNotes_TextChanged(object sender, EventArgs e)
        {
            saveNotes.Enabled = true;
        }

        private void deleteNotes_Click(object sender, EventArgs e)
        {
            string key = GetKey();
            string topic = "";

            if (key != "d")
                GetRecordId(key, counterUserPicture1.Tag.ToString(), null, counterEnemyPicture1.Tag.ToString(), null, out topic);
            else
                GetRecordId(key, counterUserPicture1.Tag.ToString(), counterUserPicture2.Tag.ToString(), counterEnemyPicture1.Tag.ToString(), counterEnemyPicture2.Tag.ToString(), out topic);

            lolDb.DeleteEntry(topic, key);
            LoadCountersData(true);
        }

        private void databaseList_SelectedIndexChanged(object sender, EventArgs e)
        {
            Settings.Default.SelectedDb = databaseList.SelectedItem.ToString();
            lolDb.Filename = Settings.Default.SelectedDb + ".lolhq";
            LoadCountersData(true);
        }

        private void counterPicture_DoubleClick(object sender, EventArgs e)
        {
            if ((sender as PictureBox).Tag == null)
                return;

            if (!infoList.Items.Contains((sender as PictureBox).Tag.ToString()))
                return;

            tabContainer.SelectedTab = tabChampionInformation;
            LoadChampionInformation((sender as PictureBox).Tag.ToString());
        }

        #endregion

        #region Counter Picking Overview
        private void LoadOverviewData()
        {
            if (String.IsNullOrEmpty((string)databaseList2.SelectedItem))
                return;



            // get stats
            int total, solo, duo, jungling;
            lolDb.GetStats(out total, out solo, out duo, out jungling);

            // calculate combinations
            IntX tmpN = new IntX(1), tmpR = new IntX(1), result = new IntX(0);
            for (int i = 1; i < riotLib.Data.Count; i++)
                tmpN = tmpN * i;

            for (int i = 1; i < riotLib.Data.Count - 2; i++)
                tmpR = tmpR * i;

            tmpR = tmpR * 2;
            result = tmpN / tmpR;

            // output the results
            lOverviewSolo.Text = solo.ToString() + " (" + ((double)solo / double.Parse(result.ToString()) * 100f).ToString("F1") + "% of " + result.ToString() + ")";
            lOverviewJungling.Text = jungling.ToString() + " (" + ((double)jungling / (double.Parse(result.ToString()) * 100f)).ToString("F1") + "% of " + result.ToString() + ")";
            lOverviewDuo.Text = duo.ToString();
            lOverviewTotal.Text = (solo + duo + jungling).ToString();


        }

        private void overviewLoadButton_Click(object sender, EventArgs e)
        {
            // save currently selected DB so we can restore it
            string oldDb = lolDb.Filename;

            lolDb.Filename = databaseList2.SelectedItem.ToString() + ".lolhq";

            LoadOverviewData();

            overviewList.Items.Clear();
            overviewList.AllColumns.Clear();


            // populate counterpicks list
            OLVColumn firstCol = new OLVColumn("", "");
            firstCol.Width = 150;
            firstCol.Groupable = false;

            firstCol.AspectGetter = delegate(object row)
            {
                return ((RiotDataStruct)row).Name;
            };
            firstCol.ImageGetter = delegate(object rowObject)
            {
                return ((RiotDataStruct)rowObject).Name;
            };
            overviewList.AllColumns.Add(firstCol);


            foreach (RiotDataStruct champ in riotLib.Data)
            {
                OLVColumn col = new OLVColumn(champ.Name, "");
                col.Width = 32;
                col.Groupable = false;
                col.IsHeaderVertical = true;
                col.Sortable = false;
                col.Tag = lolDb.Filename;

                col.AspectGetter = delegate(object row)
                {
                    if (((RiotDataStruct)row).Name == String.Empty)
                        return String.Empty;

                    lolDb.Filename = col.Tag.ToString();
                    List<ChampCountersListStruct> counters = lolDb.GetCounters("s", ((RiotDataStruct)row).Name, champ.Name);
                    lolDb.Filename = oldDb;
                    foreach (ChampCountersListStruct item in counters)
                        if (item.Name == champ.Name)
                            return item.Score;
                    return String.Empty;
                };
                col.ImageGetter = delegate(object row)
                {
                    if (((RiotDataStruct)row).Name == String.Empty)
                        return champ.Name;

                    return String.Empty;
                };
                overviewList.AllColumns.Add(col);
            }

            overviewList.RebuildColumns();

            overviewList.FormatCell += delegate(object sndr, FormatCellEventArgs eargs)
            {
                if (eargs.RowIndex != 0 && eargs.ColumnIndex != 0 && !String.IsNullOrEmpty(eargs.SubItem.Text))
                    eargs.SubItem.BackColor = ColorFromHSV((Double.Parse(eargs.SubItem.Text) + 200f) / 200f * 70f + 30f, 0.9, 0.9);
            };

            RiotDataStruct r = new RiotDataStruct();
            // empty line for first column/row
            r.Name = String.Empty;

            List<RiotDataStruct> list = new List<RiotDataStruct>();
            list.Add(r);
            list.AddRange(riotLib.Data);

            overviewList.SetObjects(list);

            // reset the db
            lolDb.Filename = oldDb;
        }

        private void tOverviewName_TextChanged(object sender, EventArgs e)
        {
            if (tOverviewName.Text.Length < 1)
                overviewCreateButton.Enabled = overviewCopyButton.Enabled = false;

            overviewCreateButton.Enabled = overviewCopyButton.Enabled = true;
        }

        private void overviewDeleteButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete " + databaseList2.Text + " database?", "Delete Database", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                File.Delete(Application.StartupPath + @"\" + databaseList2.Text + ".lolhq");
                LoadDbList();
                tOverviewName.Text = "";
            }
        }

        private void overviewCopyButton_Click(object sender, EventArgs e)
        {
            overviewCopyButton.Enabled = false;
            File.Copy(Application.StartupPath + @"\" + databaseList2.Text + ".lolhq", Application.StartupPath + @"\" + tOverviewName.Text + ".lolhq");
            LoadDbList();
            databaseList.Text = databaseList2.Text = tOverviewName.Text;
            tOverviewName.Text = "";
        }

        private void overviewImportButton_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                File.Copy(openFileDialog.FileName, Application.StartupPath + @"\" + Path.GetFileName(openFileDialog.FileName));
                LoadDbList();
                databaseList.Text = databaseList2.Text = Path.GetFileNameWithoutExtension(openFileDialog.FileName);
            }
        }

        private void overviewExportButton_Click(object sender, EventArgs e)
        {
            if (saveFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                File.Copy(Application.StartupPath + @"\" + databaseList2.Text + ".lolhq", saveFileDialog.FileName);
                MessageBox.Show("Database has been exported");
            }
        }
        #endregion

        #region Champion Information

        private void infoList_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadChampionInformation(riotLib.GetChampionByDisplayName(infoList.SelectedItem.ToString()).Name);
        }


        private void LoadChampionInformation(string champName)
        {
            RiotDataStruct data = riotLib.GetChampionByName(champName);

            infoList.SelectedItem = data.DisplayName;

            // fill general data
            infoDisplayName.Text = data.DisplayName;
            infoTitle.Text = data.Title;
            infoTags.Text = data.Tags.Replace(",", ", ");
            infoDescription.Text = data.Description;
            infoTips.Text = data.Tips.Replace("*", "\r\n\r\n* ").Trim();
            infoOpponentTips.Text = data.OpponentTips.Replace("*", "\r\n\r\n* ").Trim();
            infoIcon.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + data.IconPath);

            // populate stats table
            infoStats.AutoGenerateColumns = false;
            List<CompareStatsStruct> list = new List<CompareStatsStruct>();
            list.Add(new CompareStatsStruct()
            {
                Name = "Range",
                Base1 = data.Range.ToString("F1"),
                Level1 = "",
                Level18 = data.Range.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Move Speed",
                Base1 = data.MoveSpeed.ToString("F1"),
                Level1 = "",
                Level18 = data.MoveSpeed.ToString("F1")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Attack",
                Base1 = data.AttackBase.ToString("F1"),
                Level1 = data.AttackLevel.ToString("F1"),
                Level18 = (data.AttackBase + (data.AttackLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Armor",
                Base1 = data.ArmorBase.ToString("F1"),
                Level1 = data.ArmorLevel.ToString("F1"),
                Level18 = (data.ArmorBase + (data.ArmorLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Magic Resist",
                Base1 = data.MagicResistBase.ToString("F1"),
                Level1 = data.MagicResistLevel.ToString("F1"),
                Level18 = (data.MagicResistBase + (data.MagicResistLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Health",
                Base1 = data.HealthBase.ToString("F1"),
                Level1 = data.HealthLevel.ToString("F1"),
                Level18 = (data.HealthBase + (data.HealthLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Health Regen",
                Base1 = data.HealthRegenBase.ToString("F1"),
                Level1 = data.HealthRegenLevel.ToString("F1"),
                Level18 = (data.HealthRegenBase + (data.HealthRegenLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Mana",
                Base1 = data.ManaBase.ToString("F1"),
                Level1 = data.ManaLevel.ToString("F1"),
                Level18 = (data.ManaBase + (data.ManaLevel * 18)).ToString("F")
            });
            list.Add(new CompareStatsStruct()
            {
                Name = "Mana Regen",
                Base1 = data.ManaRegenBase.ToString("F1"),
                Level1 = data.ManaRegenLevel.ToString("F1"),
                Level18 = (data.ManaRegenBase + (data.ManaRegenLevel * 18)).ToString("F")
            });

            infoStats.DataSource = list;

            // ratings
            infoRatingAttack.Value = (int)data.RatingAttack;
            infoRatingDefense.Value = (int)data.RatingDefense;
            infoRatingMagic.Value = (int)data.RatingMagic;
            infoRatingDifficulty.Value = (int)data.RatingDifficulty;

            // skins
            infoSkinsList.Items.Clear();
            foreach (RiotSkinsStruct skin in riotLib.Skins)
            {
                if (skin.ChampionId == data.Id)
                {
                    if (String.IsNullOrEmpty(skin.DisplayName))
                        infoSkinsList.Items.Add("Base");
                    else
                        infoSkinsList.Items.Add(skin.DisplayName);
                }
            }
            infoSkinsList.SelectedItem = "Base";
            LoadSkin();

            // abilities
            foreach (RiotAbilitiesStruct ability in riotLib.Abilities)
            {
                if (ability.ChampionId != data.Id)
                    continue;

                if (ability.Rank == 1)
                {
                    infoAbilityNameP.Text = "(Passive) " + ability.Name;
                    infoAbilityEffectP.Text = ability.Effect.Replace("<br>", "\n");
                    infoAbilityIconP.Image = Image.FromFile(LoLAssetsPath + @"images\championScreens\abilities\" + ability.IconPath);
                }
                else if (ability.Rank == 2)
                {
                    infoAbilityNameQ.Text = "(Q) " + ability.Name;
                    infoAbilityEffectQ.Text = ability.Effect.Replace("<br>", "\n");
                    infoAbilityIconQ.Image = Image.FromFile(LoLAssetsPath + @"images\championScreens\abilities\" + ability.IconPath);
                    infoAbilityCostQ.Text = String.IsNullOrEmpty(ability.Cost) ? "" : "Cost: " + ability.Cost;
                    infoAbilityCooldownQ.Text = String.IsNullOrEmpty(ability.Cooldown) ? "" : "Cooldown: " + ability.Cooldown;
                }
                else if (ability.Rank == 3)
                {
                    infoAbilityNameW.Text = "(W) " + ability.Name;
                    infoAbilityEffectW.Text = ability.Effect.Replace("<br>", "\n");
                    infoAbilityIconW.Image = Image.FromFile(LoLAssetsPath + @"images\championScreens\abilities\" + ability.IconPath);
                    infoAbilityCostW.Text = String.IsNullOrEmpty(ability.Cost) ? "" : "Cost: " + ability.Cost;
                    infoAbilityCooldownW.Text = String.IsNullOrEmpty(ability.Cooldown) ? "" : "Cooldown: " + ability.Cooldown;
                }
                else if (ability.Rank == 4)
                {
                    infoAbilityNameE.Text = "(E) " + ability.Name;
                    infoAbilityEffectE.Text = ability.Effect.Replace("<br>", "\n");
                    infoAbilityIconE.Image = Image.FromFile(LoLAssetsPath + @"images\championScreens\abilities\" + ability.IconPath);
                    infoAbilityCostE.Text = String.IsNullOrEmpty(ability.Cost) ? "" : "Cost: " + ability.Cost;
                    infoAbilityCooldownE.Text = String.IsNullOrEmpty(ability.Cooldown) ? "" : "Cooldown: " + ability.Cooldown;
                }
                else if (ability.Rank == 5)
                {
                    infoAbilityNameR.Text = "(R) " + ability.Name;
                    infoAbilityEffectR.Text = ability.Effect.Replace("<br>", "\n");
                    infoAbilityIconR.Image = Image.FromFile(LoLAssetsPath + @"images\championScreens\abilities\" + ability.IconPath);
                    infoAbilityCostR.Text = String.IsNullOrEmpty(ability.Cost) ? "" : "Cost: " + ability.Cost;
                    infoAbilityCooldownR.Text = String.IsNullOrEmpty(ability.Cooldown) ? "" : "Cooldown: " + ability.Cooldown;
                }
            }

            gInfoInformation.Visible = gInfoAbilities.Visible = gInfoSkins.Visible = gInfoStatistics.Visible = true;
        }


        private void infoSkinsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadSkin();
        }


        private void LoadSkin()
        {
            // get skin's display name (if it's Base, than it's an empty string in DB)
            string skinDisplayName = infoSkinsList.SelectedItem.ToString() == "Base" ? "" : infoSkinsList.SelectedItem.ToString();

            RiotDataStruct data = riotLib.GetChampionByDisplayName(infoDisplayName.Text);

            foreach (RiotSkinsStruct skin in riotLib.Skins)
            {
                if (skin.DisplayName == skinDisplayName && skin.ChampionId == data.Id)
                {
                    infoPortrait.Image = Image.FromFile(LoLAssetsPath + @"images\champions\" + skin.PortraitPath);
                    break;
                }
            }
        }


        #endregion

        


    }
}
